local skynet = require "skynet"
local cluster = require "skynet.cluster"
local filelog = require "filelog"
local tabletool = require "tabletool"
require "fishenum"

local TablesvrHelper = {}
local server

function TablesvrHelper:init(base)
    server = base
end

function TablesvrHelper:get_server()
    return server
end

function TablesvrHelper:sendmsg_to_alltableplayer(msgname, ...)
    local table_data = server.table_data
    local rids = {}
    --通知座位上的玩家
    for _, seat in ipairs(table_data.seats) do
        table.insert(rids, seat.rid)
    end

    for _, wait in pairs(table_data.waits) do
        table.insert(rids, wait.rid)
    end
    cluster.send("gatenode", ".router", "notify", rids, "fish." .. msgname, ...)
end

function TablesvrHelper:sendmsg_to_othertableplayer(rid, msgname, ...)
    local table_data = server.table_data
    local rids = {}
    --通知座位上的玩家
    for _, seat in ipairs(table_data.seats) do
        if seat.rid ~= rid then
            table.insert(rids, seat.rid)
        end
    end

    for _, wait in pairs(table_data.waits) do
        table.insert(rids, wait.rid)
    end
    cluster.send("gatenode", ".router", "notify", rids, "fish." .. msgname, ...)
end

function TablesvrHelper:sendmsg_to_tableplayer(seat, msgname, ...)
    cluster.send("gatenode", ".router", "notify", {seat.rid}, "fish." .. msgname, ...)
end

function TablesvrHelper:sendmsg_to_allwaitplayer(msgname, ...)
    local table_data = server.table_data
    local rids = {}
    for rid, wait in pairs(table_data.waits) do
        table.insert(rids, wait.rid)
    end
    cluster.send("gatenode", ".router", "notify", rids, "fish." .. msgname, ...)
end

function TablesvrHelper:sendmsg_to_waitplayer(wait, msgname, ...)
    cluster.send("gatenode", ".router", "notify", {wait.rid}, "fish." .. msgname, ...)
end

function TablesvrHelper:sendmsg_to_roomsvr(msgname, ...)
    skynet.send(".router", "lua", msgname, ...)
end

function TablesvrHelper:callmsg_to_roomsvr(msgname, ...)
    return skynet.call(".router", "lua", msgname, ...)
end

function TablesvrHelper:sendmsg_to_datasvr(msgname, ...)
    cluster.send("datanode", ".router", msgname, ...)
end

function TablesvrHelper:callmsg_to_datasvr(msgname, ...)
    return cluster.call("datanode", ".router", msgname, ...)
end

function TablesvrHelper:sendmsg_to_gatesvr(msgname, ...)
    cluster.send("gatenode", ".router", msgname, ...)
end

function TablesvrHelper:callmsg_to_gatesvr(msgname, ...)
    local stat, ret = pcall(cluster.call, "gatenode", ".router", msgname, ...)
    if not stat then return false end
    return ret
end

-- 同步消息
function TablesvrHelper:s2csynclauncher()
    -- filelog.warn("s2csynclauncher ===>", self)
    local msg = {
        id      = self.Id,
        etype   = self.Type,
        pos_x   = tostring(self.PosX),
        pos_y   = tostring(self.PosY),
        angle   = tostring(self.Angle),
        stat    = self.Stat,
        level   = self.Level,
        cd      = self.CD,
        point   = self.Point,
    }
    TablesvrHelper:sendmsg_to_alltableplayer("s2csynclauncherN", {launcher = msg})
end

-- 同步给自己以外的玩家
function TablesvrHelper:s2csyncexlauncher()
    -- filelog.warn("s2csyncexlauncher ===>", self)
    local table_data = server.table_data
    local msg = {
        id      = self.Id,
        etype   = self.Type,
        pos_x   = tostring(self.PosX),
        pos_y   = tostring(self.PosY),
        angle   = tostring(self.Angle),
        stat    = self.Stat,
        level   = self.Level,
        cd      = self.CD,
        point   = self.Point,
    }
    
    TablesvrHelper:sendmsg_to_othertableplayer(self.Rid, "s2csynclauncherN", {launcher = msg})
end

function TablesvrHelper:s2csyncbullet()
    -- filelog.warn("s2csyncbullet ===>", self)
    local msg = {
        id      = self.Id,
        etype   = self.Type,
        r       = self.R,
        stat    = self.Stat,
        level   = self.Level,
        speed   = self.Speed,
        angle   = tostring(self.Angle),
        rid     = self.Rid,
        target  = self.Target,
    }
    TablesvrHelper:sendmsg_to_alltableplayer("s2csyncbulletN", {bullet = msg})
end

-- 同步给自己以外的玩家
function TablesvrHelper:s2csyncexbullet()
    -- filelog.warn("s2csyncexbullet ===>", self)
    local table_data = server.table_data
    local msg = {
        id      = self.Id,
        etype   = self.Type,
        r       = self.R,
        stat    = self.Stat,
        level   = self.Level,
        speed   = self.Speed,
        angle   = tostring(self.Angle),
        rid     = self.Rid,
        target  = self.Target,
    }
    TablesvrHelper:sendmsg_to_othertableplayer(self.Rid, "s2csyncbulletN", {bullet = msg})
end

function TablesvrHelper:s2csyncfish()
    -- filelog.warn("s2csyncfish ===>", self)
    local msg = {
        id      = self.Id,
        etype   = self.Type,
        r       = self.R,
        pos_x   = tostring(self.PosX),
        pos_y   = tostring(self.PosY),
        offset_x   = tostring(self.OffsetX),
        offset_y   = tostring(self.OffsetY),
        angle   = tostring(self.Angle),
        stat    = self.Stat,
        level   = self.Level,
        speed   = self.Speed,
        posindex    = self.PosIdx,
        dead_type   = self.DeadType,
        point   = self.Point,
        ts      = tostring(self.Ts),
        group   = self.Group,
    }
    TablesvrHelper:sendmsg_to_alltableplayer("s2csyncfishN", {fish = msg})
end

function TablesvrHelper:copy_table_gameinfo(gameinfo)
    local table_data = server.table_data
    gameinfo.idx = table_data.idx
    gameinfo.state = table_data.state
    gameinfo.name = table_data.conf.name
    gameinfo.room_type = table_data.conf.room_type
    gameinfo.game_type = table_data.conf.game_type
    gameinfo.max_player_num = table_data.conf.max_player_num
    gameinfo.cur_player_num = table_data.sitdown_player_num
    gameinfo.create_user_rid = table_data.conf.create_user_rid
    gameinfo.create_user_rolename = table_data.conf.create_user_rolename
    gameinfo.create_time = table_data.conf.create_time
    gameinfo.table_code = table_data.conf.table_code
    gameinfo.create_user_logo = table_data.conf.create_user_logo
    gameinfo.min_carry_diamond = table_data.conf.min_carry_diamond
    gameinfo.leave_carry_diamond = table_data.conf.leave_carry_diamond

    gameinfo.seats = {}
    gameinfo.player_infos = {}
    gameinfo.fishes = {}
    local seatinfo, playerinfo
    for index, seat in pairs(table_data.seats) do
        seatinfo = {}
        playerinfo = {}
        self:copy_seatinfo(seatinfo, seat)
        table.insert(gameinfo.seats, seatinfo)
        self:copy_playerinfo(playerinfo, seat)
        table.insert(gameinfo.player_infos, playerinfo)
    end

    gameinfo.is_public = table_data.conf.is_public
    gameinfo.tip = table_data.tip or 0
    gameinfo.curr_round_code = table_data.conf.curr_round_code
    local fishes = server.logic.gamelogic.getallfishes()
    local fishinfo
    for _, fish in pairs(fishes) do
        fishinfo = {}
        self:copy_fishinfo(fishinfo, fish)
        table.insert(gameinfo.fishes, fishinfo)
    end
    gameinfo.baseshootlevel = table_data.conf.baseshootlevel
    gameinfo.service_fee_rate = table_data.conf.service_fee_rate
end

function TablesvrHelper:copy_seatinfo(seatinfo, seat)
    seatinfo.rid = seat.rid
    seatinfo.index = seat.index
    seatinfo.state = seat.state
    seatinfo.diamond = seat.diamond
    seatinfo.shoot_level = seat.shootlevel
    seatinfo.shootstat = seat.shootstat
    if seat.items then
        seatinfo.items = {}
        for _, item in pairs(seat.items) do
            table.insert(seatinfo.items, {
                id = item.id,
                itype = item.type,
                num = item.num,
            })
        end
    end
    if seat.launcher then
        seatinfo.launcher = {}
        self:copy_launcherinfo(seatinfo.launcher, seat.launcher)
    end
end

function TablesvrHelper:copy_playerinfo(playerinfo, seat)
    playerinfo.rid = seat.rid
    playerinfo.rolename = seat.playerinfo.rolename
    playerinfo.logo = seat.playerinfo.logo or ''
    playerinfo.sex = seat.playerinfo.sex or 0
    playerinfo.ip_addr = seat.playerinfo.ip_addr or ''
    playerinfo.diamond = seat.playerinfo.diamond or 0
    playerinfo.introduce = seat.playerinfo.introduce or ''
    playerinfo.upvoted_num = seat.playerinfo.upvoted_num
    playerinfo.downvoted_num = seat.playerinfo.downvoted_num
    playerinfo.gps_addr = seat.playerinfo.gps_addr
    playerinfo.logoframe = seat.playerinfo.logoframe or 100
end

function TablesvrHelper:copy_fishinfo(fishinfo, fish)
    fishinfo.id         = fish.Id
    fishinfo.etype      = fish.Type
    fishinfo.r          = fish.R
    fishinfo.pos_x      = tostring(fish.PosX)
    fishinfo.pos_y      = tostring(fish.PosY)
    fishinfo.offset_x   = tostring(fish.OffsetX)
    fishinfo.offset_y   = tostring(fish.OffsetY)
    fishinfo.angle      = tostring(fish.Angle)
    fishinfo.stat       = fish.Stat
    fishinfo.level      = fish.Level
    fishinfo.speed      = fish.Speed
    fishinfo.posindex   = fish.PosIdx
    fishinfo.dead_type  = fish.DeadTypev
    fishinfo.point      = fish.Point
    fishinfo.ts         = tostring(fish.Ts)
    return fishinfo
end

function TablesvrHelper:copy_launcherinfo(launcherinfo, launcher)
    launcherinfo.id      = launcher.Id
    launcherinfo.etype   = launcher.Type
    launcherinfo.pos_x   = launcher.PosX
    launcherinfo.pos_y   = launcher.PosY
    launcherinfo.angle   = launcher.Angle
    launcherinfo.stat    = launcher.Stat
    launcherinfo.level   = launcher.Level
    launcherinfo.cd      = launcher.CD
end

return TablesvrHelper